<template>
  <page-meta :root-font-size="fontSize + 'px'"></page-meta>

  <view class="page-container">
    <CustomHeader :title="pageModule.title" :border-line="false" />

    <scroll-view class="scroll-container" :style="{ top: height + 'px' }" :scroll-top="pageModule.pageScrollTop"
      scroll-with-animation scroll-y @scroll="pageModule.onScroll">
      <view :class="['scroll_content', popupModule.show && 'show']">
        <text class="top-hint">下面是你的作答情况，<text class="stress">点击选项处 </text>可查看解析。</text>
        <view class="content">
          <template v-for="(item, index) in pageModule.pageData" :key="index">
            <text v-if="item.str.includes('#')" :id="'scroll' + pageModule.getAnswer(item.str)?.topic_id"
              @click="pageModule.handleClickItem(item.str, index)"
              :class="['input', item.className, pageModule.currentIndex == index && STATUS_CSS_MODULE.active]"
              :data-content="item.value">
              {{ item.str }}
            </text>
            <text v-else>{{ item.str }}</text>
          </template>
        </view>
      </view>
    </scroll-view>

    <view :class="['analysis-container', popupModule.show && 'show']">
      <view class="top">
        <text>解析</text>
        <image @click="popupModule.close(false)" class="icon"
          src="https://rwstatic.tentons.cn/web/Lesson/images/close-icon.png">
        </image>
      </view>
      <view class="center">
        <text>正确答案：</text>
        <text class="answer">{{ popupModule.answer }}</text>
      </view>
      <view class="bottom">
        <view class="text">
          <text>{{ popupModule.analysis }}</text>
        </view>
      </view>
    </view>
  </view>
</template>

<script lang="ts" setup>
import { nextTick, reactive, ref, useCssModule, onMounted } from "vue";
import { replaceChar, rootFontSize, debounce } from "@/utils/util";
import CustomHeader from "@/components/customHeader.vue";
import API from "@/api";

type Options = { className: string, op_idx: string, option: string };

type PageData = { className?: string, str: string, value: string };

const props = defineProps({
  section_id: {
    type: [String, Number]
  },
  topic_id: {
    type: [String, Number]
  }
});

// 公用常量
let query: UniApp.SelectorQuery | null = null;

const fontSize = rootFontSize();

const height = ref(parseInt(getApp().globalData!.pageTop));

const STATUS_CSS_MODULE = useCssModule('status');

/**
 * 页面数据模块
 */
const pageModule = reactive({
  title: '随课自检',
  pageData: [] as PageData[],
  currentIndex: -1,
  options: [] as Options[],
  answerList: [] as any[],
  scrollTop: 0,
  pageScrollTop: 0,
  async init(callback?: Function) {
    try {
      const resultData: any = await API.getCourseAnswerAnalysis({
        section_id: props.section_id,
        topic_id: props.topic_id
      });
      resultData?.title && (this.title = resultData.title);
      const [options, maxLength] = this.getFormatOptionData(resultData?.options);
      this.options = options;
      this.answerList = resultData?.analysis || [];
      this.pageData = this.getFormatHtmlData(resultData?.content, this.answerList, maxLength);
    } catch (e) {
      console.error(e);
    } finally {
      callback && callback();
    }
  },
  getAnswer(params: string | number, field?: 'answer' | 'u_answer') {
    let index: string | number = params;
    typeof params == "string" && (index = params.substring(params.lastIndexOf('#') + 1, params.length));
    const answerData = this.answerList.find((item) => {
      if (typeof params == "string") {
        return item.idx == index;
      } else {
        return item.topic_id == index;
      }
    });
    if (field) {
      const optionData = this.options.find((item) => item.op_idx == answerData[field])?.option || '-';
      return [answerData, optionData];
    } else return answerData;
  },
  handleClickItem(params: string | number, index: number) {
    if (this.currentIndex == index) return;

    this.currentIndex = index;

    const [answerData, optionData] = this.getAnswer(params, 'answer');

    popupModule.open(answerData, optionData, true);
  },
  getFormatOptionData(list: Options[] = []): [any[], number] {
    let maxLength = 0;
    list.forEach((item) => {
      item.option = item.op_idx + ')' + item.option.split(' ')[1];
      item.option.length > maxLength && (maxLength = item.option.length);
    });
    return [list, maxLength];
  },
  getFormatHtmlData(str: string, answer_list: any[], maxLength: number) {
    let newList: string[] = [], mapKey = [];
    if (str && answer_list?.length) {
      const list = answer_list.reverse();
      for (let i = 0; i < list.length; i++) {
        let placeholder = '';
        let area = JSON.parse(list[i].answer_seat);
        let id = list[i].idx.toString();
        let placeholderLength = maxLength - id.toString().length;
        for (let i = 0; i < placeholderLength; i++) placeholder += '#';
        mapKey.push(placeholder + id);
        str = replaceChar(str, area[0], area[1], '#');
      }
      newList = str.split('#');
      let startIndex = 1;
      for (let i = mapKey.length - 1; i >= 0; i--) {
        newList.splice(startIndex, 0, mapKey[i]);
        startIndex += 2;
      }
    }
    return newList.map((str: string) => {
      let className = '', value = '';
      if (str.includes('#')) {
        const [answerData, optionData] = this.getAnswer(str, 'u_answer');
        value = optionData;
        className = answerData.answer == answerData.u_answer ? STATUS_CSS_MODULE.success : STATUS_CSS_MODULE.error;
      }
      return {
        className,
        value,
        str
      }
    });
  },
  setLocation(id: string) {
    query = uni.createSelectorQuery();
    query!.select(id).boundingClientRect((data: any) => {
      this.pageScrollTop = (data.top - height.value - data.height * 3) + this.scrollTop;
    }).exec();
  },
  onScroll: debounce(function (e: any) {
    pageModule.scrollTop = e.target.scrollTop;
  }, 0, false)
});

/**
 * 弹窗数据模块
 */
const popupModule = reactive({
  show: false,
  answer: '',
  analysis: '',
  open(answer: any, options: any, popupShow: boolean) {
    this.show = popupShow;
    this.answer = options;
    this.analysis = answer.analysis;
    nextTick(() => {
      pageModule.setLocation('#scroll' + answer.topic_id);
    });
  },
  close(popupShow: boolean) {
    this.show = false;
  }
});


onMounted(() => {
  pageModule.init(() => {
    const answerData = pageModule.getAnswer(Number(props.topic_id));
    const index = pageModule.pageData.findIndex((item) => (item.str.includes('#') && item.str.includes(answerData.idx)));
    pageModule.handleClickItem(Number(props.topic_id), index);
  });
});
</script>

<style scoped lang="scss">
@mixin fontStyle($size) {
  font-size: #{ $size }rem;
  font-family: xiaolai;
  color: $uni-text-color;
}

.page-container {
  width: 100vw;
  height: 100vh;
  background-color: #fff;

  .scroll-container {
    position: absolute;
    width: 37.5rem;
    bottom: 0;
    left: 50%;
    transform: translateX(-50%);

    .scroll_content {
      padding: 2rem 20px 0 20px;
      padding-bottom: calc(2rem + constant(safe-area-inset-bottom));
      padding-bottom: calc(2rem + env(safe-area-inset-bottom));

      &.show {
        padding-bottom: calc(35rem + constant(safe-area-inset-bottom));
        padding-bottom: calc(35rem + env(safe-area-inset-bottom));
      }

      .top-hint {
        @include fontStyle(1.5);
        color: $uni-text-color-grey;

        .stress {
          color: #E8A71B;
        }
      }

      .content {
        @include fontStyle(1.7);
        margin-top: 1rem;
        line-height: 3rem;

        .input {
          position: relative;
        }
      }
    }
  }

  .analysis-container {
    width: 100%;
    position: fixed;
    display: flex;
    flex-direction: column;
    left: 0;
    bottom: 0;
    height: 33rem;
    background-color: #fff;
    border-top: 2px solid $uni-text-color;
    border-right: 2px solid $uni-text-color;
    border-left: 2px solid $uni-text-color;
    border-top-left-radius: 2.5rem;
    border-top-right-radius: 2.5rem;
    padding: 1.6rem 2rem 0 2rem;
    box-sizing: border-box;
    padding-bottom: calc(1.6rem + constant(safe-area-inset-bottom));
    padding-bottom: calc(1.6rem + env(safe-area-inset-bottom));
    transform: translateY(100%);
    transition: transform .2s ease;

    &.show {
      transform: translateY(0);
    }

    .top {
      @include fontStyle(1.6);
      position: relative;
      margin-bottom: 2.4rem;
      display: flex;
      align-items: center;
      justify-content: center;

      .icon {
        position: absolute;
        height: 2.4rem;
        width: 2.4rem;
        right: 0;
      }
    }

    .center {
      @include fontStyle(1.6);
      display: flex;
      align-items: center;
      line-height: 1;
      margin-bottom: 1.4rem;

      .answer {
        font-size: 1.5rem;
        height: 2.2rem;
        line-height: 2.2rem;
        padding: 0 2.5rem;
        background-color: #ECF3D2;
      }
    }

    .bottom {
      @include fontStyle(1.5);
      overflow: scroll;
      color: $uni-text-color-grey;

      &::-webkit-scrollbar {
        display: none;
        width: 0;
        height: 0;
        color: transparent;
      }
    }
  }
}
</style>

<style lang="scss" module="status">
.base {
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  height: 100%;
  width: 100%;
  background-color: #FFEBCA;
  content: attr(data-content);
  text-align: center;
  line-height: 1;
  padding: 0.3rem 0 0.1rem 0;
}

.success {
  &::after {
    @extend .base;
    background-color: #ECF3D2;
    border: 1px solid transparent;
  }

  &.active {
    &::after {
      border: 1px solid #9AA435;
    }
  }
}

.error {
  &::after {
    @extend .base;
    color: #EC6357;
    background-color: #FFE6E6;
    border: 1px solid transparent;
  }

  &.active {
    &::after {
      border: 1px solid #EC6357;
    }
  }
}
</style>
